home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / make / input.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  10KB  |  402 lines

  1. /*************************************************************************
  2.  *
  3.  *  m a k e :   i n p u t . c
  4.  *
  5.  *  Parse a makefile
  6.  *========================================================================
  7.  * Edition history
  8.  *
  9.  *  #    Date                         Comments                       By
  10.  * --- -------- ---------------------------------------------------- ---
  11.  *   1    ??                                                         ??
  12.  *   2 23.08.89 new name tree structure introduced to speed up make,
  13.  *              testname introduced to shrink the memory usage       RAL
  14.  *   3 30.08.89 indention changed                                    PSH,RAL
  15.  *   4 03.09.89 fixed LZ eliminated                                  RAL
  16.  *   5 06.09.89 ; command added                                      RAL
  17.  * ------------ Version 2.0 released ------------------------------- RAL
  18.  *
  19.  *************************************************************************/
  20.  
  21.  
  22. #include "h.h"
  23.  
  24.  
  25. static struct name *lastrrp;
  26. static struct name *freerp = (struct name *)NULL;
  27.  
  28. void init()
  29. {
  30.   if( (suffparray = (struct name **) malloc( sizesuffarray *
  31.            sizeof(struct name *)))  == (struct name **) NULL)
  32.      fatal("No memory for suffarray",(char *)0,0);
  33.   if ((*suffparray = (struct name *)malloc(sizeof (struct name)))
  34.                           == (struct name *)0)
  35.      fatal("No memory for name",(char *)0,0);
  36.   (*suffparray)->n_next = (struct name *)0;
  37.  
  38.   if ((str1 = malloc(LZ1)) == (char *)0)
  39.      fatal("No memory for str1",(char *)0,0);
  40.   str1s.ptr = &str1;
  41.   str1s.len = LZ1;
  42.   if ((str2 = malloc(LZ2)) == (char *)0)
  43.      fatal("No memory for str2",(char *)0,0);
  44.   str2s.ptr = &str2;
  45.   str2s.len = LZ2;
  46. }
  47.  
  48. void strrealloc(strs)
  49. struct str *strs;
  50. {
  51.   strs->len *= 2;
  52.   if( (*strs->ptr = realloc( *strs->ptr, strs->len)) == (char *) NULL)
  53.        fatal("No memory for string reallocation",(char *)0,0);
  54. }
  55.  
  56. /*
  57.  *    Intern a name.  Return a pointer to the name struct
  58.  */
  59. struct name *newname(name)
  60. char *name;
  61. {
  62.   register struct name *rp;
  63.   register struct name *rrp;
  64.   register char        *cp;
  65.  
  66.   register int           i;
  67.   register char         *suff;   /* ptr. to suffix in current name */
  68.   register struct name **sp;     /* ptr. to ptr. to chain of names */
  69.  
  70.   if ( (suff = suffix(name)) != (char *)NULL) {
  71.      for (i = 1, sp = suffparray, sp++;
  72.           i <= maxsuffarray && strcmp(suff, (*sp)->n_name) != 0;
  73.           sp++,i++);
  74.      if (i > maxsuffarray) {
  75.         if ( i >= sizesuffarray) { /* must realloc suffarray */
  76.            sizesuffarray *= 2;
  77.            if( (suffparray = (struct name **) realloc((char *) suffparray,
  78.                 sizesuffarray * sizeof(struct name *))) == (struct name **) NULL)
  79.               fatal("No memory for suffarray",(char *)0,0);
  80.         }
  81.         maxsuffarray++;
  82.         sp = &suffparray[i];
  83.         if ((*sp = (struct name *)malloc(sizeof (struct name)))
  84.                                    == (struct name *)0)
  85.            fatal("No memory for name",(char *)0,0);
  86.         (*sp)->n_next = (struct name *)0;
  87.         if ((cp = malloc(strlen(suff)+1)) == (char *)0)
  88.            fatal("No memory for name",(char *)0,0);
  89.         strcpy(cp, suff);
  90.         (*sp)->n_name = cp;
  91.      }
  92.   }
  93.   else
  94.      sp = suffparray;
  95.  
  96.   for ( rp = (*sp)->n_next, rrp = *sp; rp; rp = rp->n_next, rrp = rrp->n_next )
  97.      if (strcmp(name, rp->n_name) == 0)  return rp;
  98.  
  99.   if ( freerp ==  (struct name *)NULL) {
  100.      if ((rp = (struct name *)malloc(sizeof (struct name))) == (struct name *)0)
  101.         fatal("No memory for name",(char *)0,0);
  102.   }
  103.   else  {
  104.      rp = freerp;
  105.      freerp =  (struct name *)NULL;
  106.   }
  107.   rrp->n_next = rp;
  108.   rp->n_next = (struct name *)0;
  109.   if ((cp = malloc(strlen(name)+1)) == (char *)0)
  110.      fatal("No memory for name",(char *)0,0);
  111.   strcpy(cp, name);
  112.   rp->n_name = cp;
  113.   rp->n_line = (struct line *)0;
  114.   rp->n_time = (time_t)0;
  115.   rp->n_flag = 0;
  116.   lastrrp = rrp;
  117.  
  118.   return rp;
  119. }
  120.  
  121. /*
  122.  *     Test a name.
  123.  *     If the name already exists return the ptr. to its name structure.
  124.  *     Else if the file exists 'intern' the name and return the ptr.
  125.  *     Otherwise don't waste memory and return a NULL pointer
  126.  */
  127. struct name *testname(name)
  128. char *name;
  129. {
  130.   register struct name *rp;
  131.  
  132.   lastrrp = (struct name *)NULL;
  133.   rp = newname( name);
  134.   if (rp->n_line || rp->n_flag & N_EXISTS)
  135.      return(rp);
  136.   modtime(rp);
  137.   if (rp->n_flag & N_EXISTS)
  138.      return(rp);
  139.   if (lastrrp != (struct name *)NULL) {
  140.      free (rp->n_name);
  141.      lastrrp->n_next = (struct name *)NULL;
  142.      freerp = rp;
  143.   }
  144.   return((struct name *)NULL);
  145. }
  146.  
  147.  
  148.  
  149. /*
  150.  *    Add a dependant to the end of the supplied list of dependants.
  151.  *    Return the new head pointer for that list.
  152.  */
  153. struct depend *newdep(np, dp)
  154. struct name   *np;
  155. struct depend *dp;
  156. {
  157.   register struct depend *rp;
  158.   register struct depend *rrp;
  159.  
  160.  
  161.   if ((rp = (struct depend *)malloc(sizeof (struct depend)))
  162.           == (struct depend *)0)
  163.     fatal("No memory for dependant",(char *)0,0);
  164.   rp->d_next = (struct depend *)0;
  165.   rp->d_name = np;
  166.  
  167.   if (dp == (struct depend *)0)  return rp;
  168.  
  169.   for (rrp = dp; rrp->d_next; rrp = rrp->d_next) ;
  170.  
  171.   rrp->d_next = rp;
  172.  
  173.   return dp;
  174. }
  175.  
  176.  
  177. /*
  178.  *    Add a command to the end of the supplied list of commands.
  179.  *    Return the new head pointer for that list.
  180.  */
  181. struct cmd *newcmd(str, cp)
  182. char       *str;
  183. struct cmd *cp;
  184. {
  185.   register struct cmd *rp;
  186.   register struct cmd *rrp;
  187.   register char       *rcp;
  188.  
  189.  
  190.   if (rcp = strrchr(str, '\n'))  *rcp = '\0';    /*  Loose newline  */
  191.  
  192.   while (isspace(*str))  str++;
  193.  
  194.   if (*str == '\0')  return cp;        /*  If nothing left, the exit  */
  195.  
  196.   if ((rp = (struct cmd *)malloc(sizeof (struct cmd))) == (struct cmd *)0)
  197.     fatal("No memory for command",(char *)0,0);
  198.   rp->c_next = (struct cmd *)0;
  199.   if ((rcp = malloc(strlen(str)+1)) == (char *)0)
  200.     fatal("No memory for command",(char *)0,0);
  201.   strcpy(rcp, str);
  202.   rp->c_cmd = rcp;
  203.  
  204.   if (cp == (struct cmd *)0)  return rp;
  205.  
  206.   for (rrp = cp; rrp->c_next; rrp = rrp->c_next) ;
  207.  
  208.   rrp->c_next = rp;
  209.  
  210.   return cp;
  211. }
  212.  
  213.  
  214. /*
  215.  *    Add a new 'line' of stuff to a target.  This check to see
  216.  *    if commands already exist for the target.  If flag is set,
  217.  *    the line is a double colon target.
  218.  *
  219.  *    Kludges:
  220.  *    i)  If the new name begins with a '.', and there are no dependents,
  221.  *        then the target must cease to be a target.  This is for .SUFFIXES.
  222.  *    ii) If the new name begins with a '.', with no dependents and has
  223.  *        commands, then replace the current commands.  This is for
  224.  *        redefining commands for a default rule.
  225.  *    Neither of these free the space used by dependents or commands,
  226.  *    since they could be used by another target.
  227.  */
  228.  
  229. void newline(np, dp, cp, flag)
  230. struct name   *np;
  231. struct depend *dp;
  232. struct cmd    *cp;
  233. int            flag;
  234. {
  235.   bool                  hascmds = FALSE;  /*  Target has commands  */
  236.   register struct line *rp;
  237.   register struct line *rrp;
  238.  
  239.  
  240.   /* Handle the .SUFFIXES case */
  241.   if (np->n_name[0] == '.' && !dp && !cp) {
  242.     for (rp = np->n_line; rp; rp = rrp) {
  243.         rrp = rp->l_next;
  244.         free(rp);
  245.     }
  246.     np->n_line = (struct line *)0;
  247.     np->n_flag &= ~N_TARG;
  248.     return;
  249.   }
  250.  
  251.   /* This loop must happen since rrp is used later. */
  252.   for ( rp = np->n_line, rrp = (struct line *)0; rp; rrp = rp, rp = rp->l_next)
  253.     if (rp->l_cmd)  hascmds = TRUE;
  254.  
  255.   if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  256.     /* Handle the implicit rules redefinition case */
  257.     if (np->n_name[0] == '.' && dp == (struct depend *)0) {
  258.         np->n_line->l_cmd = cp;
  259.         return;
  260.     }
  261.     else
  262.         error("Commands defined twice for target %s", np->n_name);
  263.   if (np->n_flag & N_TARG)
  264.     if (!(np->n_flag & N_DOUBLE) != !flag)        /* like xor */
  265.         error("Inconsistent rules for target %s", np->n_name);
  266.  
  267.   if ((rp = (struct line *)malloc(sizeof (struct line))) == (struct line *)0)
  268.     fatal("No memory for line",(char *)0,0);
  269.   rp->l_next = (struct line *)0;
  270.   rp->l_dep = dp;
  271.   rp->l_cmd = cp;
  272.  
  273.   if (rrp)
  274.          rrp->l_next = rp;
  275.   else
  276.          np->n_line = rp;
  277.  
  278.   np->n_flag |= N_TARG;
  279.   if (flag)  np->n_flag |= N_DOUBLE;
  280. }
  281.  
  282.  
  283. /*
  284.  *    Parse input from the makefile, and construct a tree structure
  285.  *    of it.
  286.  */
  287. void input(fd)
  288. FILE *fd;
  289. {
  290.   char          *p;        /*  General  */
  291.   char          *q;
  292.   register char *a;
  293.   st